/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dataentry;

import com.singularsys.jep.JepException;
import com.singularsys.jep.ParseException;
import enums.Type;
import java.util.ArrayList;
import java.util.Stack;

/**
 *
 * @author i.capurro
 */
public abstract class Question {
    private String name;
    private Rule valueRule = null;
    private Rule questionRule = null;
    private Rule quantityRule = null;
    private Type type = Type.INT;
    private int length;
    private boolean notEmpty = false;
    private boolean notAcceptDuplicateValues = false;
    private Question funnelQuestion = null;

    public Question(String name) {
        this.name = name;
        this.length = 1;
    }
    
    public String getName() {
        return name;
    }

    public void setNotAcceptDuplicateValues(boolean notAcceptDuplicateValues) {
        this.notAcceptDuplicateValues = notAcceptDuplicateValues;
    }

    public void setNotEmpty(boolean notEmpty) {
        this.notEmpty = notEmpty;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Rule getQuestionRule() {
        return questionRule;
    }

    public void setQuestionRule(String questionRule) throws Exception {
        this.questionRule = new Rule(questionRule);
        
    }

    public Rule getQuantityRule() {
        return quantityRule;
    }

    public boolean isNotEmpty() {
        return notEmpty;
    }

    public void setQuantityRule(String quantityRule) throws ParseException {
        this.quantityRule = new Rule(quantityRule);
    }
    
    public void setFunnelQuestion(Question funnelQuestion) {
        this.funnelQuestion = funnelQuestion;
    }

    public Rule getValueRule() {
        return valueRule;
    }

    public void setValueRule(String valueRule) throws Exception {
        Rule r = new Rule(valueRule);
        ArrayList l = r.getVariables();
        //if ((!r.getVariables().contains(this.name)) || (r.getVariables().size() > 1)) {
        //    throw new Exception ("Error al definir regla de rango para " + this.name);
        //} else {
            this.valueRule = r;
        //}
    }
    
    public boolean isValidValue(String value) throws Exception {
        
        // Chequeo de valores duplicados (si amerita)
        if ((notAcceptDuplicateValues) && (hasValue(value))) {
            return false;
        }
        // Chequeo de embudo (si amerita), el valor debe pertenecer a las respuestas de la pregunta funnelQuestion
        if (funnelQuestion != null) {
            if (!funnelQuestion.hasValue(value)) {
                return false;
            }
        }
        // Chequeo de reglas de aceptacion, rangos, utilizando el motor JEP (se realiza siempre)
        if (this.valueRule != null) {
            if (this.type == Type.INT) {
                try {
                    int val = Integer.parseInt(value);
                    valueRule.addVariable(name, val);
                    return valueRule.evaluate();
                } catch (NumberFormatException | JepException e) {
                    return false;
                }
            } else {
                return true;
            }
        } else {
            return true;
        }
    }
    
    abstract public int getLength ();
    
    abstract public void pushAnswer (String val);
    
    abstract public void popAnswer ();
    
    abstract public String getAnswer();
    
    abstract public Stack getAnswers();
    
    abstract public void emptyAnswers();
    
    abstract public boolean hasValue(String val);
     
}
